package de.fhffm.gaertnerei.gui;

/**
 * @author Riad Hassani & Julian Schmücker
 */
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.regex.Pattern;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.text.MaskFormatter;

import de.fhffm.gaertnerei.exceptions.EingabeException;
import de.fhffm.gaertnerei.tabellen.Aussaat;
import de.fhffm.gaertnerei.tabellen.Duenger;
import de.fhffm.gaertnerei.tabellen.PflanzOrt;
import de.fhffm.gaertnerei.tabellen.Pflanze;

@SuppressWarnings("serial")
public class AussaatBearbeitenFenster extends JFrame implements ActionListener {

	private JButton buttonSpeichern = new JButton("Speichern");
	private JButton buttonAbbrechen = new JButton("Abbrechen");
	private JButton buttonPflanze = new JButton("+");
	private JButton buttonDuenger = new JButton("+");
	
	private JLabel labelPflanze = new JLabel("Pflanze");
	private JLabel labelDuenger = new JLabel("Duenger");
	private JLabel labelOrt = new JLabel("Pflanz Ort");
	private JLabel labelDuengerMenge = new JLabel("DuengerMenge");
	private JLabel labelDatum= new JLabel("Datum");
	private JLabel labelKilogramm = new JLabel ("Kilogramm");
	private JLabel labelUeberschrift = new JLabel("Aussaat bearbeiten");
	
	private JTextField textfeldPflanze = new JTextField(8);
	private JTextField textfeldDuenger = new JTextField(8);
	private JTextField textfeldDuengerMenge = new JTextField(8);

	private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd.MM.yyyy");
	
	private JFormattedTextField textfeldDatum ;
	
	private MaskFormatter datumFormat= null;
	
	private Date aktuellesDatum = new Date();
	
	private JPanel panelEingabe = new JPanel();
	private JPanel panelButton = new JPanel();
	private JPanel panelUeberschrift = new JPanel();

	private String pflanzeString = null;
	private String duengerString = null;
	private String ortString = null;
	private String datumString;
	private String duengerMengeString = null;
	private String[] orte = {"Topf klein","Topf mittel","Topf groß","Feld","Beet"};
	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	private JComboBox ortListe = new JComboBox(orte);
	
	private double duengerMengeDouble = 0;
	
	private List<String> ausgewaehlteZeile;
	
	StringBuilder stringBuilder = new StringBuilder();

	public AussaatBearbeitenFenster(List<String> ausgewaehlteZeile){
		
		this.ausgewaehlteZeile = ausgewaehlteZeile;
		setzeTextfeldEigenschaften();
		setzeDatumtextfeldFeld();
		bestandteileAnordnen();
		ereignissensorenAnmeldung();
		fuelleTextfelder();
		erstelleFenster();
	}
	
	@Override
	public void actionPerformed(ActionEvent e) {
		
		Object obj = e.getSource();
		
		if(obj == buttonAbbrechen){
			dispose();
		}
		
		if(obj == buttonPflanze){
			new PflanzenTabelle(textfeldPflanze);
		}
		
		if(obj == buttonDuenger){
			new DuengerTabelle(textfeldDuenger);
		}
		
		if(obj == buttonSpeichern){
			
			if(ueberpruefeEingabe()){
				
				ueberpruefePflanzOrt();
				speicherAenderungen();
				speichernEnde();
				
			}else{
				System.out.println("Eingabe Fehler");
			}
		}
	}
	
	private void setzeTextfeldEigenschaften() {
		
		textfeldPflanze.setEnabled(false); // Textfeld kann nicht beschrieben werden
		textfeldDuenger.setEnabled(false);
		textfeldDuengerMenge.setToolTipText("Menge des eingesetzten Düngers in Kilogramm");		
	}

	private void erstelleFenster() {
		
		setTitle("Aussaat bearbeiten");	
		setSize(400,500);
		setLocationRelativeTo(null);
		setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		pack();
		setVisible(true);
		setResizable(false);
	}

	private void setzeDatumtextfeldFeld() {
		
		try {
			datumFormat = new MaskFormatter("##.##.####");
		} catch (ParseException e) {
			e.printStackTrace();
		}
		
		textfeldDatum = new JFormattedTextField(datumFormat);
		panelEingabe.add(textfeldDatum);
		
	}

	private void fuelleTextfelder() {
		
		// Bei der Aussaat ist der Listenplatz 0 für die ID!
		// da wir die zu bearbeitende Aussaat nicht anders Identifizieren können.
		textfeldDatum.setText(ausgewaehlteZeile.get(1));
		String[] teilString = ausgewaehlteZeile.get(3).split(Pattern.quote(" ")); // Kilogramm entfernen
		textfeldDuengerMenge.setText(teilString[0]);
		ortListe.setSelectedItem((ausgewaehlteZeile.get(2)));
		textfeldPflanze.setText(ausgewaehlteZeile.get(4));
		textfeldDuenger.setText(ausgewaehlteZeile.get(5));
	}
	
	private void ereignissensorenAnmeldung(){
		
		buttonSpeichern.addActionListener(this);
		buttonAbbrechen.addActionListener(this);
		buttonPflanze.addActionListener(this);
		buttonDuenger.addActionListener(this);
	}
	
	private void bestandteileAnordnen(){
		
		GroupLayout neuePflanzeFensterLayout = new GroupLayout(getContentPane());
		getContentPane().setLayout(neuePflanzeFensterLayout);
		
		neuePflanzeFensterLayout.setAutoCreateGaps(true);
		neuePflanzeFensterLayout.setAutoCreateContainerGaps(true);
		
		neuePflanzeFensterLayout.setVerticalGroup(neuePflanzeFensterLayout.createSequentialGroup().
				addComponent(panelUeberschrift).
				addComponent(panelEingabe).
				addComponent(panelButton)
		);
		
		neuePflanzeFensterLayout.setHorizontalGroup(neuePflanzeFensterLayout.createParallelGroup().
				addComponent(panelUeberschrift).
				addComponent(panelEingabe).
				addComponent(panelButton)
		);		
	
		panelUeberschriftAnordnen();
		panelEingabeAnordnen();
		panelButtonAnordnen();
	}

	private void panelUeberschriftAnordnen(){
		
		panelUeberschrift.setLayout(new FlowLayout());
		panelUeberschrift.add(labelUeberschrift);
		labelUeberschrift.setFont(new Font("Times new Roman", Font.BOLD, 22));
	}
		
	private void panelEingabeAnordnen(){
		
		GroupLayout eingabePanelLayout = new GroupLayout(panelEingabe);
		panelEingabe.setLayout(eingabePanelLayout);
		
		eingabePanelLayout.setAutoCreateGaps(true);
		eingabePanelLayout.setAutoCreateContainerGaps(true);
		
		eingabePanelLayout.setVerticalGroup(eingabePanelLayout.createSequentialGroup( ).
					addGroup(eingabePanelLayout.createParallelGroup( GroupLayout.Alignment.BASELINE ).
						addComponent( labelPflanze ).
						addComponent( textfeldPflanze ).
						addComponent( buttonPflanze )
					).
					addGroup(eingabePanelLayout.createParallelGroup( GroupLayout.Alignment.BASELINE ).
					  	addComponent( labelDuenger ).
						addComponent( textfeldDuenger ).
						addComponent( buttonDuenger )
					).
					addGroup(eingabePanelLayout.createParallelGroup( GroupLayout.Alignment.BASELINE ).
						  	addComponent( labelOrt ).
							addComponent( ortListe )
					).
			  		addGroup(eingabePanelLayout.createParallelGroup( GroupLayout.Alignment.BASELINE ).
			  			addComponent( labelDuengerMenge ).
			  			addComponent( textfeldDuengerMenge ).
			  			addComponent(labelKilogramm)
					).
			  		addGroup(eingabePanelLayout.createParallelGroup( GroupLayout.Alignment.BASELINE ).
						addComponent( labelDatum ).
					  	addComponent( textfeldDatum )));
						
		eingabePanelLayout.setHorizontalGroup(eingabePanelLayout.createParallelGroup( ).addGroup(eingabePanelLayout.createSequentialGroup( ).
					addGroup( eingabePanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false ).
						addComponent( labelPflanze, GroupLayout.DEFAULT_SIZE,GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE ).
						addComponent( labelDuenger,GroupLayout.DEFAULT_SIZE,GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE ).
						addComponent( labelOrt,GroupLayout.DEFAULT_SIZE,GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE ).
						addComponent( labelDuengerMenge, GroupLayout.DEFAULT_SIZE,GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE ).
						addComponent( labelDatum,GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE,Short.MAX_VALUE )
					).
					addGroup( eingabePanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false ).
						addComponent( textfeldPflanze, GroupLayout.DEFAULT_SIZE,GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE ).
						addComponent( textfeldDuenger,GroupLayout.DEFAULT_SIZE,GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE ).
						addComponent( ortListe,GroupLayout.DEFAULT_SIZE,GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE ).
						addComponent( textfeldDuengerMenge, GroupLayout.DEFAULT_SIZE,GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE ).
						addComponent( textfeldDatum,GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE,Short.MAX_VALUE )
					).
					addGroup( eingabePanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false ).
						addComponent( buttonPflanze, GroupLayout.DEFAULT_SIZE,GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE ).
						addComponent( buttonDuenger,GroupLayout.DEFAULT_SIZE,GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE ).
						addComponent( labelKilogramm, GroupLayout.DEFAULT_SIZE,GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE ))));
	}

	private void panelButtonAnordnen(){
		
		panelButton.setLayout(new FlowLayout());
		panelButton.add(buttonSpeichern);
		panelButton.add(buttonAbbrechen);
	}
	
	private void ueberpruefePflanzOrt() {
		
		EntityManagerFactory factory;
		factory = Persistence.createEntityManagerFactory("chilidatenbank");
		EntityManager em = factory.createEntityManager();
		em.getTransaction().begin();
		
	    Query q = em.createQuery("SELECT p FROM PflanzOrt p WHERE  p.ort = :name");
	        	q.setParameter("name",ortString);
	
	        
	   if(q.getResultList().isEmpty()){
		   em.close();
		   System.out.println("Pflanz Ort noch nicht vorhanden!");
		   fuegePflanzOrtEin();

	   }else{
		   em.close();
		   System.out.println("Pflanz Ort schon vorhanden!");
	   }
		
	}

	private void fuegePflanzOrtEin() {
		
		EntityManagerFactory factory;
		factory = Persistence.createEntityManagerFactory("chilidatenbank");
		EntityManager em = factory.createEntityManager();
		em.getTransaction().begin();
		
		PflanzOrt pflanzort = new PflanzOrt();
		
		pflanzort.setOrt(ortString);
		em.persist(pflanzort);
		em.getTransaction().commit();
		em.close();		
	}

	private void speicherAenderungen() {
		/*
		 * Alle aenderungen werden nacheinander gespeichert!
		 */
		
		int originalAussaat = Integer.parseInt(ausgewaehlteZeile.get(0));
		EntityManagerFactory factory;
		factory = Persistence.createEntityManagerFactory("chilidatenbank");
		EntityManager em = factory.createEntityManager();
		em.getTransaction().begin();
				  
		Query q = em.createQuery("SELECT p FROM Pflanze p WHERE p.sorte =:sorte");
				  q.setParameter("sorte", pflanzeString);
		
		Pflanze pflanze = (Pflanze) q.getSingleResult();
		
		q = em.createQuery("SELECT d FROM Duenger d WHERE d.duengerMarke =:marke");
		    q.setParameter("marke", duengerString);
		  
		 Duenger duenger = (Duenger) q.getSingleResult();
		 
	    q = em.createQuery("SELECT p FROM PflanzOrt p WHERE  p.ort = :name");
     		q.setParameter("name",ortString);
     	
     	PflanzOrt pflanzOrt = (PflanzOrt) q.getSingleResult();
		 
		 q = em.createQuery("SELECT a FROM Aussaat a WHERE a.aussaatID =:ID");
		 	 q.setParameter("ID", originalAussaat);
		 
		 Aussaat aussaat = (Aussaat) q.getSingleResult();
		 
		 
		/*
		 * vorherige Aussaat aus der Liste der jeweiligen Attribute löschen
		 * und die "neue" Aussaat hinzufügen
		 */
		 pflanze.getAussaat().remove(pflanze);
		 duenger.getAussaat().remove(pflanze);
		 pflanzOrt.getAussaat().remove(pflanze);
		 
		 aussaat.setPflanze(pflanze);
		 aussaat.setDuenger(duenger);
		 aussaat.setPflanzOrt(pflanzOrt);
		 
		 pflanze.getAussaat().add(aussaat);
		 duenger.getAussaat().add(aussaat);
		 pflanzOrt.getAussaat().add(aussaat);
		 
		 
		 q = em.createQuery("UPDATE Aussaat a SET a.aussaatDatum =:datum, a.duengerMenge =:duengerMenge WHERE a.aussaatID =:ID");
			  q.setParameter("datum", datumString);
			  q.setParameter("duengerMenge", duengerMengeString);
			  q.setParameter("ID", originalAussaat);
			  
			  q.executeUpdate();
		 
		 em.getTransaction().commit();
		 em.close(); 
		 
	}

	private boolean ueberpruefeEingabe() {
		
		boolean pruefe = false;
		try {
			ueberpruefeDatum();
			pruefe = hohleEingabe();
		} catch (EingabeException e) {
			System.out.println("Eingabe Fehlt");
		} catch (NumberFormatException n){
			System.out.println("Bitte Zahlen eingeben!");
			JOptionPane.showMessageDialog(null,"Bitte für die Dünger Menge nur Zahlen eingeben.","Fehler",JOptionPane.ERROR_MESSAGE);
		}
		return pruefe;
	}
	
	private void ueberpruefeDatum() throws EingabeException {
        
		/*Das Aktuelle Datum wird in einen String mit dem format dd.mm.yyyy umgewandelt.
		Dan wird das aktuelle Datum wieder als Date gespeichert nur mit dem vorher definierten format
		so kann das aktuelle Datum mit dem eingegebenen Datum verglichen werden */
		
		datumString = textfeldDatum.getText();
		Date eingegebenesDatum = null;				
		String aktuellesDatumString = simpleDateFormat.format(aktuellesDatum);
		String[] teilString = datumString.split(Pattern.quote(".")); // Das eingegebene Datum wird gesplittet
		int jahr = Integer.parseInt(teilString[2]);			
		 
		try {
			
			 eingegebenesDatum = simpleDateFormat.parse(datumString);
			 aktuellesDatum = simpleDateFormat.parse(aktuellesDatumString);
			
		} catch (ParseException e) {
			e.printStackTrace();
		}
		
		if(eingegebenesDatum.after(aktuellesDatum)){
			throw new EingabeException("Das eingegebene Datum darf nicht nach dem aktuellem Datum liegen!");
			
			/*
			 *  Eingegebenes Datum ist ungültig wenn kein Tag, Monat oder Jahr angegeben wird bsp.: 00.00.0000	
			 *  um dies zu überprüfen wird der vorher gesplittete String genutzt.
			 *  Oder auch wenn das eingegebene Jahr vor 1970 ist
			 */
			
		}else if((teilString[0]).equals("00") || (teilString[1].equals("00") || teilString[2].equals("0000") || teilString[2].substring(0, 1).equals("0"))){
			
		    throw new EingabeException("Das Datum muss im format tt.mm.yyyy eingegeben werden und darf nicht 0 sein");
		    
		}else if(jahr < 1970){
			
			throw new EingabeException("Das eingegebene Datum  darf nicht vor dem Jahr 1970 liegen");
		
		}else if(eingegebenesDatum.equals(aktuellesDatum)){
			
			System.out.println("Alles ok");
		}
	}
	
	private boolean hohleEingabe() throws EingabeException,NumberFormatException {
		
		pflanzeString = textfeldPflanze.getText();
		duengerString = textfeldDuenger.getText();
		ortString = (String) ortListe.getSelectedItem();
		duengerMengeDouble = Double.parseDouble(textfeldDuengerMenge.getText());
		stringBuilder.append(duengerMengeDouble).append(" Kilogramm");
		duengerMengeString = stringBuilder.toString();
		stringBuilder.setLength(0);
		datumString = textfeldDatum.getText();
		
		if(isEingabeLeer()){
			
			throw new EingabeException("Eine oder mehrere Eingaben fehlen, bitte keine negativen Zahlen/Nullwerte eingeben!");
			
		}else{

			return true;

		}
	}
	
	private boolean isEingabeLeer() {
		
		if(pflanzeString.length() == 0 || duengerString.length() == 0 || ortString.length() == 0 || duengerMengeDouble <= 0.0) {		
			return true;
		}else{
			return false;
		}
	}
	
	private void speichernEnde() {
		
		Object[] options = {"Fertig!","Weiter bearbeiten"};
		int selected = JOptionPane.showOptionDialog(null,"Aussaat erfolgreich bearbeitet!", "Änderungen gespeichert", JOptionPane.YES_NO_OPTION,
					   JOptionPane.QUESTION_MESSAGE, null , options, options[1]);
		
		switch(selected){
		case 0:
			dispose();
			break;
		case 1:
			dispose();
			new BearbeitenTabellenFenster(3);
		}
	}
}